package com.ficus.road.maintain.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ficus.road.maintain.client.Response.*;
import com.ficus.road.maintain.client.XljVideoClient;
import com.ficus.road.maintain.dao.ManagementUnitScoreDetailDao;
import com.ficus.road.maintain.dao.xlj.XljManagementDao;
import com.ficus.road.maintain.util.MyDateUtil;
import com.mongodb.DuplicateKeyException;
import com.mongodb.InsertOptions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ficus.road.maintain.client.Response.ManagementUnitResponse;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 下立交视频封装
 */
@Service
@Slf4j
public class XljVideoService {

    @Autowired
    XljManagementDao xljManagementDao;
    @Autowired
    XljVideoClient xljVideoClient;

    @Autowired
    ManagementUnitScoreDetailDao managementUnitScoreDetailDao;

    /**
     * 登录
     */
    public String LogIn() {
        try {
            return xljVideoClient.LogIn();
        } catch (JsonProcessingException e) {
            log.info("城道接口登陆失败");
            return null;
        }
    }

    /**
     * 获取视频地址
     *
     * @param xljId
     * @return
     */
    public GeiXljVideoResponse geiXljVideo(String xljId, String cookie) {

        try {
            //新建返回值
            GeiXljVideoResponse geiXljVideoResponse = new GeiXljVideoResponse();

            //获取摄像头信息
            List<CameraInformationResponse.CameraInformation> cameraInformationList = xljVideoClient.GetCameraInformation(xljId, cookie);
            for (CameraInformationResponse.CameraInformation cameraInformation : cameraInformationList) {
                GeiXljVideoResponse.XljVideo xljVideo = new GeiXljVideoResponse.XljVideo();
                //获取视频地址
                VideoAddressResponse.VideoInformation videoInformation = xljVideoClient.GetVideoAddress(cameraInformation.getCameraId(), cameraInformation.getChannelId(), cookie);
//                list.add(videoInformation);
                xljVideo.setCameraName(cameraInformation.getCameraName());
                xljVideo.setAddress(videoInformation.getAddress());
                geiXljVideoResponse.getVideoAddress().add(xljVideo);
            }
            return geiXljVideoResponse;

        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 管理单位履职（前端接口拿数据）
     *
     * @return
     */
    public ManagementUnitResponse ManagementUnit() {
        List<GetScoreDetailsResponse> byQuery = new ArrayList<>();
        int dayOfMonth = MyDateUtil.getDayOfMonth(new Date());
        String date = null;
        //如当前日在1日-19日之间，则取上上个月排行，否则取上月排行
        if (dayOfMonth > 0 && dayOfMonth <= 19) {
            date = MyDateUtil.dateFormatStr(MyDateUtil.getFirstDayOfLastNMonth(2), "yyyy-MM");
        } else {
            date = MyDateUtil.dateFormatStr(MyDateUtil.getFirstDayOfLastMonth(), "yyyy-MM");
        }
        Criteria Id = Criteria.where("date").is(date);
        Query query = new Query(Id);
        byQuery = xljManagementDao.findByQuery(query);
        if (byQuery.isEmpty()) {
            int num = 1;
            while (true) {
                Id = Criteria.where("date").is(date);
                query = new Query(Id);
                byQuery = xljManagementDao.findByQuery(query);
                if (byQuery.isEmpty()) {
                    date = MyDateUtil.dateFormatStr(MyDateUtil.getFirstDayOfLastNMonth(num), "yyyy-MM");
                    num++;
                } else {
                    break;
                }
            }
        }
        // 找到分数最高的三个元素
        List<GetScoreDetailsResponse> highestThree = byQuery.stream()
                .sorted(Comparator.comparingDouble(GetScoreDetailsResponse::getTotal).reversed())
                .limit(3)
                .collect(Collectors.toList());

        // 找到分数最低的三个元素
        List<GetScoreDetailsResponse> lowestThree = byQuery.stream()
                .sorted(Comparator.comparingDouble(GetScoreDetailsResponse::getTotal))
                .limit(3)
                .collect(Collectors.toList());
        ManagementUnitResponse managementUnitResponse = new ManagementUnitResponse();
        List<GetScoreDetailsResponse> higList = new ArrayList<>();
        for (GetScoreDetailsResponse getScoreDetailsResponse : highestThree) {
            GetScoreDetailsResponse getScore = new GetScoreDetailsResponse();
            getScore.setUnitId(getScoreDetailsResponse.getUnitId());
            getScore.setUnitName(getScoreDetailsResponse.getUnitName());
            getScore.setTotal(getScoreDetailsResponse.getTotal());
            higList.add(getScore);
        }
        List<GetScoreDetailsResponse> lowList = new ArrayList<>();
        for (GetScoreDetailsResponse getScoreDetailsResponse : lowestThree) {
            GetScoreDetailsResponse getScore = new GetScoreDetailsResponse();
            getScore.setUnitId(getScoreDetailsResponse.getUnitId());
            getScore.setUnitName(getScoreDetailsResponse.getUnitName());
            getScore.setTotal(getScoreDetailsResponse.getTotal());
            lowList.add(getScore);
        }
        managementUnitResponse.setHighwayUnitScoreList(higList);
        managementUnitResponse.setRoadUnitScoreList(lowList);
        return managementUnitResponse;
    }

    /**
     * 单位履职详细评分
     *
     * @param unid
     * @return
     */
    public List<ManagementUnitDetailResponse> getManagementUnitDetail(String unid) {
        int dayOfMonth = MyDateUtil.getDayOfMonth(new Date());
        List<Details> byQuery = new ArrayList<>();
        String date = null;
        //如当前日在1日-19日之间，则取上上个月排行，否则取上月排行
        if (dayOfMonth > 0 && dayOfMonth <= 19) {
            date = MyDateUtil.dateFormatStr(MyDateUtil.getFirstDayOfLastNMonth(2), "yyyy-MM");
        } else {
            date = MyDateUtil.dateFormatStr(MyDateUtil.getFirstDayOfLastMonth(), "yyyy-MM");
        }
        Criteria Id = Criteria.where("p_unid").is(unid).and("date").is(date);
        Query query = new Query(Id);
        byQuery = managementUnitScoreDetailDao.findByQuery(query);
        if (byQuery.isEmpty()) {
            int num = 1;
            while (true) {
                Id = Criteria.where("p_unid").is(unid).and("date").is(date);
                query = new Query(Id);
                byQuery = managementUnitScoreDetailDao.findByQuery(query);
                if (byQuery.isEmpty()) {
                    date = MyDateUtil.dateFormatStr(MyDateUtil.getFirstDayOfLastNMonth(num), "yyyy-MM");
                    num++;
                } else {
                    break;
                }
            }
        }
        List<ManagementUnitDetailResponse> list = new ArrayList<>();
        ManagementUnitDetailResponse sceneAndHouse = new ManagementUnitDetailResponse();
        sceneAndHouse.setFirstProject("现场+内业考核");
        for (Details details : byQuery) {
            // 如果是现场内业考核
            if (details.getProjectName().equals("现场考核") || details.getProjectName().equals("内业考核")) {
                sceneAndHouse.getDetails().addAll(details.getChildren());
            } else {
                ManagementUnitDetailResponse managementUnitDetailResponse = new ManagementUnitDetailResponse();
                managementUnitDetailResponse.setFirstProject(details.getProjectName());
                managementUnitDetailResponse.getDetails().addAll(details.getChildren());
                for (Children detail : managementUnitDetailResponse.getDetails()) {
                    detail.setScore(detail.getGetScore());
                    detail.setDeductReason(detail.getDeductScoreReason());
                    double v = managementUnitDetailResponse.getTotalScore() + detail.getGetScore();
                    managementUnitDetailResponse.setTotalScore(v);
                }
                double v = (managementUnitDetailResponse.getTotalScore() * details.getProportion()) / 100.0;
                managementUnitDetailResponse.setTotalScore(v);
                list.add(managementUnitDetailResponse);
            }
        }
        for (Children detail : sceneAndHouse.getDetails()) {
            detail.setScore(detail.getGetScore());
            detail.setDeductReason(detail.getDeductScoreReason());
            double v = sceneAndHouse.getTotalScore() + detail.getGetScore();
            sceneAndHouse.setTotalScore(v);
        }
        double v = (sceneAndHouse.getTotalScore() * 40) / 100.0;
        sceneAndHouse.setTotalScore(v);
        list.add(sceneAndHouse);

        return list;
    }

    /**
     * 管理单位履职（存储到Mongo）
     *
     * @return
     */
    //    @Scheduled(cron = "0 1/2 * * * ?")
    @Scheduled(cron = "0 0 14 20-25 * ?", zone = "GMT+8:00")
    public void ManagementUnit1() {
        try {
            String cookie = LogIn();
            //通过时间获得unid
            LocalDate localDate = LocalDate.now().minusMonths(1);
            SectionScoreResponse sectionScoreResponse = xljVideoClient.GetSectionScoreByTime(cookie, localDate);
            String date = MyDateUtil.dateFormatStr(MyDateUtil.getFirstDayOfLastMonth(), "yyyy-MM");
            //创建返回值
            List<GetScoreDetailsResponse> getScoreDetailsResponseList = new ArrayList<>();
            //用获得的每一个unid调用标段分数详细接口获取数据
            for (SectionScoreResponse.Section datum : sectionScoreResponse.getData()) {
                //通过前端发来的unid获取当月标段得分，以及标段分数详细评分细则
                GetScoreDetailsResponse getScoreDetailsResponse = new GetScoreDetailsResponse();
                ScoreDetailsResponse scoreDetailsResponse = xljVideoClient.GetScoreDetailsByUnid(datum.getUnid(), cookie);
                if (scoreDetailsResponse != null) {
                    List<Details> data = scoreDetailsResponse.getData();
                    if (data != null && !data.isEmpty()) {
                        for (Details scoreDetail : data) {
                            try {
                                scoreDetail.setLocalDate(localDate);
                                scoreDetail.setDate(date);
                                managementUnitScoreDetailDao.saveOrUpdate(scoreDetail);
                            } catch (Exception e) {
                                // 处理重复键异常的情况，例如跳过该条数据
                                System.out.println("遇到重复键异常，跳过插入：" + scoreDetail);
                            }
                        }
                    }
                }
                //获得评分
                getScoreDetailsResponse.setTotal(datum.getTotal());
                //获得时间
                getScoreDetailsResponse.setInspectionTime(datum.getInspectionTime());
                //获得名字
                getScoreDetailsResponse.setUnitName(datum.getSectionsName());
                //获得unitId
                getScoreDetailsResponse.setUnitId(datum.getUnid());
                //获得评分细则
//                boolean NoPointsDeducted =true;
//                for (ScoreDetailsResponse.Details scoreDetailsResponseDatum : scoreDetailsResponse.getData()) {
//                    if (scoreDetailsResponseDatum.getScoreStandard()!=null) {
//                        getScoreDetailsResponse.setScoreStandard(getScoreDetailsResponse.getScoreStandard() + scoreDetailsResponseDatum.getScoreStandard());
//                        NoPointsDeducted=false;
//                    }
//                }
//                if (NoPointsDeducted){
//                    getScoreDetailsResponse.setScoreStandard("无扣分");
//                }
                getScoreDetailsResponseList.add(getScoreDetailsResponse);
            }
            for (GetScoreDetailsResponse getScoreDetailsResponse : getScoreDetailsResponseList) {
                try {
                    if (getScoreDetailsResponse.getTotal() > 0) {
                        getScoreDetailsResponse.setDate(date);
                        xljManagementDao.saveOrUpdate(getScoreDetailsResponse);
                    }
                } catch (DuplicateKeyException e) {
                    // 处理重复键异常的情况，例如跳过该条数据
                    System.out.println("遇到重复键异常，跳过插入：" + getScoreDetailsResponse);
                }
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 城市道路工单处置详情
     */
    @Scheduled(cron = "0 0 14 * * ?", zone = "GMT+8:00")
    public void urbanRoadClient() {
        try {
            String cookie = LogIn();
            xljVideoClient.urbanRoadClient(cookie);
        } catch (Exception e) {
            log.info(e.toString());
        }
    }

    /**
     * 获取城市道路 wgs84 坐标列表
     */
    public void GetUrbanRoadGps() {
        try {
            String cookie = LogIn();
            xljVideoClient.GetUrbanRoadGps(cookie);
        } catch (Exception e) {
            log.info(e.toString());
        }
    }

    /**
     * 清空
     */
    public void ManagementUnittest() {
        xljManagementDao.deleteAll();
    }

    private static Date convertToDate(LocalDateTime localDateTime) {
        return java.sql.Timestamp.valueOf(localDateTime);
    }


    public void testUrbanRoadClient() {
        try {
            String cookie = LogIn();
            xljVideoClient.testUrbanRoadClient(cookie);
        } catch (Exception e) {
            log.info(e.toString());
        }
    }



    public JsonNode getComplainData(String yearMonth) {
        try {
            String cookie = LogIn();
            JsonNode complainData = xljVideoClient.getComplainData(cookie, yearMonth);
            return complainData;
        } catch (Exception e) {
            log.info(e.toString());
            return null;
        }
    }

    public JsonNode getComplainData1(String yearMonth) {
        try {
            String cookie = LogIn();
            JsonNode complainData = xljVideoClient.getComplainData1(cookie, yearMonth);
            return complainData;
        } catch (Exception e) {
            log.info(e.toString());
            return null;
        }
    }

    public JsonNode getComplainData2(String yearMonth) {
        try {
            String cookie = LogIn();
            JsonNode complainData = xljVideoClient.getComplainData2(cookie, yearMonth);
            return complainData;
        } catch (Exception e) {
            log.info(e.toString());
            return null;
        }
    }



}
